﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Toolkit.Web.Infastructure;
using Toolkit.Web.ExtensionMethods;

namespace Toolkit.Web.ViewComponents.Button
{
    public sealed class ButtonHtmlBuilder : ViewComponentHtmlBuilderBase
    {
        public ButtonHtmlBuilder(Button button)
            : base(button)
        {
            if (button == null)
            {
                throw new ArgumentNullException("button");
            }

            _button = button;
            CssClassNames = new ComponentCssClassNames();
        }

        private Button _button
        {
            get;
            set;
        }

        public ComponentCssClassNames CssClassNames
        {
            get;
            private set;
        }

        public override IHtmlNode Html()
        {
            return ButtonMarkup();
        }

        public IHtmlNode ButtonMarkup()
        {
            IHtmlNode htmlTag = new HtmlNode("div");
            htmlTag.MergeAttributes(_button.HtmlAttributes, true);
            htmlTag.AddClass(CssClassNames.ComponentWrapper);

            htmlTag.Attributes["tabindex"] = "0";

            if (!_button.IsEnabled)
            {
                htmlTag.AddClass(CssClassNames.Disabled);
            }

            htmlTag.Attributes["data-type"] = ((int)_button.Type).ToString();

            if (_button.ClientEventHandlers != null)
            {
                if (!string.IsNullOrEmpty(_button.ClientEventHandlers.OnBeforePrimaryAction))
                {
                    htmlTag.Attributes["data-before-action"] = _button.ClientEventHandlers.OnBeforePrimaryAction;
                }

                if (!string.IsNullOrEmpty(_button.ClientEventHandlers.OnBeforeShowMenu))
                {
                    htmlTag.Attributes["data-before-show-menu"] = _button.ClientEventHandlers.OnBeforeShowMenu;
                }

                if (!string.IsNullOrEmpty(_button.ClientEventHandlers.OnBeforeHideMenu))
                {
                    htmlTag.Attributes["data-before-hide-menu"] = _button.ClientEventHandlers.OnBeforeHideMenu;
                }
            }

            AppendNativeMarkup(htmlTag);

            htmlTag.Append(InnerWrapperMarkup());

            if (_button.IsMenuAllowed)
            {
                htmlTag.Append(MenuMarkup());
            }

            return htmlTag;
        }

        public void AppendNativeMarkup(IHtmlNode htmlTag)
        {
            if (_button.Type == ButtonType.LinkButton || _button.Type == ButtonType.SplitLinkButton)
            {
                IHtmlNode aTag = new HtmlNode("a");

                if (!string.IsNullOrEmpty(_button.LinkToUrl))
                {
                    aTag.Attributes["href"] = _button.LinkToUrl;
                }

                if (!string.IsNullOrEmpty(_button.LinkToTarget))
                {
                    aTag.Attributes["target"] = _button.LinkToTarget;
                }

                aTag.AddStyle("display", "none");

                htmlTag.Append(aTag);
            }
            else if (_button.Type == ButtonType.InputButton || _button.Type == ButtonType.SplitInputButton)
            {
                IHtmlNode inputTag = new HtmlNode("input");
                inputTag.Attributes["type"] = _button.InputType;

                if (!string.IsNullOrEmpty(_button.InputName))
                {
                    inputTag.Attributes["name"] = _button.InputName;
                }

                if (!string.IsNullOrEmpty(_button.InputValue))
                {
                    inputTag.Attributes["value"] = _button.InputValue;
                }

                inputTag.AddStyle("display", "none");

                htmlTag.Append(inputTag);
            }
        }

        public IHtmlNode InnerWrapperMarkup()
        {
            IHtmlNode htmlTag = new HtmlNode("div");

            if (!HtmlStringExtensions.IsNullOrEmpty(_button.Title) && (_button.PrimaryIconDisplay == ButtonDisplay.Top || _button.PrimaryIconDisplay == ButtonDisplay.Bottom))
            {
                htmlTag.AddClass(CssClassNames.TwoLevelPrimaryButton);
            }
            else
            {
                htmlTag.AddClass(CssClassNames.OneLevelPrimaryButton);
            }

            if (_button.PrimaryIconDisplay == ButtonDisplay.Top)
            {
                htmlTag.AddClass(CssClassNames.TopIcon);
            }
            else if (_button.PrimaryIconDisplay == ButtonDisplay.Right)
            {
                htmlTag.AddClass(CssClassNames.RightIcon);
            }
            else if (_button.PrimaryIconDisplay == ButtonDisplay.Bottom)
            {
                htmlTag.AddClass(CssClassNames.BottomIcon);
            }
            else if (_button.PrimaryIconDisplay == ButtonDisplay.Left)
            {
                htmlTag.AddClass(CssClassNames.LeftIcon);
            }

            if (_button.IsMenuAllowed)
            {
                if (_button.SecondaryIconDisplay == ButtonDisplay.Top)
                {
                    htmlTag.AddClass(_button.Type == ButtonType.DropDownButton ? CssClassNames.DropDownTop : CssClassNames.SplitTop);
                }
                else if (_button.SecondaryIconDisplay == ButtonDisplay.Right)
                {
                    htmlTag.AddClass(_button.Type == ButtonType.DropDownButton ? CssClassNames.DropDownRight : CssClassNames.SplitRight);
                }
                else if (_button.SecondaryIconDisplay == ButtonDisplay.Bottom)
                {
                    htmlTag.AddClass(_button.Type == ButtonType.DropDownButton ? CssClassNames.DropDownBottom : CssClassNames.SplitBottom);
                }
                else if (_button.SecondaryIconDisplay == ButtonDisplay.Left)
                {
                    htmlTag.AddClass(_button.Type == ButtonType.DropDownButton ? CssClassNames.DropDownLeft : CssClassNames.SplitLeft);
                }
            }

            if (HtmlStringExtensions.IsNullOrEmpty(_button.Title))
            {
                htmlTag.AddClass(CssClassNames.NoText);
            }

            htmlTag.Append(PrimaryButtonMarkup());

            if (_button.IsMenuAllowed && _button.SecondaryIconDisplay != ButtonDisplay.None)
            {
                htmlTag.Append(SecondaryButtonMarkup());
            }

            return htmlTag;
        }

        public IHtmlNode PrimaryButtonMarkup()
        {
            IHtmlNode htmlTag = new HtmlNode("div");
            htmlTag.AddClass(CssClassNames.PrimaryWrapper);

            htmlTag.Append(PrimaryTextMarkup());

            if (_button.PrimaryIconDisplay != ButtonDisplay.None)
            {
                htmlTag.Append(PrimaryIconMarkup());
            }

            return htmlTag;
        }

        public IHtmlNode PrimaryTextMarkup()
        {
            IHtmlNode htmlTag = new HtmlNode("div");
            htmlTag.AddClass("vc-text");

            if (_button.Title != null)
            {
                htmlTag.InnerHtml = _button.Title.ToHtmlString();
            }

            return htmlTag;
        }

        public IHtmlNode PrimaryIconMarkup()
        {
            IHtmlNode htmlTag = new HtmlNode("div");
            htmlTag.AddClass(CssClassNames.IconWrap);

            IHtmlNode iconTag = new HtmlNode("div");
            iconTag.MergeAttributes(_button.PrimaryIconHtmlAttributes, true);
            iconTag.AddClass("vc-icon");

            htmlTag.Append(iconTag);
            return htmlTag;
        }

        public IHtmlNode SecondaryButtonMarkup()
        {
            IHtmlNode htmlTag = new HtmlNode("div");
            htmlTag.AddClass(CssClassNames.SecondaryWrapper);

            if (_button.SecondaryIconDisplay != ButtonDisplay.None)
            {
                htmlTag.Append(SecondaryIconMarkup());
            }

            return htmlTag;
        }

        public IHtmlNode SecondaryIconMarkup()
        {
            IHtmlNode htmlTag = new HtmlNode("div");
            htmlTag.AddClass(CssClassNames.IconWrap);

            IHtmlNode iconTag = new HtmlNode("div");
            iconTag.MergeAttributes(_button.SecondaryIconHtmlAttributes, true);
            iconTag.AddClass("vc-icon");

            htmlTag.Append(iconTag);
            return htmlTag;
        }

        public IHtmlNode MenuMarkup()
        {
            IHtmlNode htmlTag = new HtmlNode("div");

            if (_button.Menu != null)
            {
                htmlTag.MergeAttributes(_button.Menu.HtmlAttributes, true);

                if (_button.Menu.OverrideTemplate != null && _button.Menu.OverrideTemplate.HasValue())
                {
                    htmlTag.ApplyTemplate(_button.Menu.OverrideTemplate);
                }
                else if (_button.Menu.Sections != null)
                {
                    foreach (ButtonMenuSection section in _button.Menu.Sections)
                    {
                        htmlTag.Append(MenuSectionMarkup(section));
                    }
                }
            }

            htmlTag.AddClass(CssClassNames.Menu);
            htmlTag.AddStyle("display", "none");
            htmlTag.Attributes["data-vc-id"] = _button.Identifier;

            return htmlTag;
        }

        public IHtmlNode MenuSectionMarkup(ButtonMenuSection section)
        {
            IHtmlNode htmlTag = new HtmlNode("div");

            if (section != null)
            {
                htmlTag.MergeAttributes(section.HtmlAttributes, true);

                if (section.OverrideTemplate != null && section.OverrideTemplate.HasValue())
                {
                    htmlTag.ApplyTemplate(section.OverrideTemplate);
                }
                else if (section.Items != null)
                {
                    foreach (HtmlTemplate template in section.Items)
                    {
                        IHtmlNode itemTag = new HtmlNode("div");
                        itemTag.AddClass(CssClassNames.MenuSectionItem);
                        itemTag.ApplyTemplate(template);
                        htmlTag.Append(itemTag);
                    }
                }
            }

            htmlTag.AddClass(CssClassNames.MenuSection);

            return htmlTag;
        }

        public class ComponentCssClassNames
        {
            public readonly string ComponentWrapper = "vc-btn";
            public readonly string Disabled = "vc-btn-disabled";
            public readonly string Active = "vc-btn-active";
            public readonly string TwoLevelPrimaryButton = "vc-btn-2h";
            public readonly string OneLevelPrimaryButton = "vc-btn-1h";
            public readonly string IconWrap = "vc-btn-iconWrap";
            public readonly string TopIcon = "vc-btn-iconTop";
            public readonly string RightIcon = "vc-btn-iconRight";
            public readonly string BottomIcon = "vc-btn-iconBottom";
            public readonly string LeftIcon = "vc-btn-iconLeft";
            public readonly string SplitTop = "vc-btn-splitTop";
            public readonly string SplitRight = "vc-btn-splitRight";
            public readonly string SplitBottom = "vc-btn-splitBottom";
            public readonly string SplitLeft = "vc-btn-splitLeft";
            public readonly string DropDownTop = "vc-btn-ddlTop";
            public readonly string DropDownRight = "vc-btn-ddlRight";
            public readonly string DropDownBottom = "vc-btn-ddlBottom";
            public readonly string DropDownLeft = "vc-btn-ddlLeft";
            public readonly string NoText = "vc-btn-noText";
            public readonly string PrimaryWrapper = "vc-btn-primary";
            public readonly string SecondaryWrapper = "vc-btn-secondary";
            public readonly string Menu = "vc-btn-menu";
            public readonly string MenuSection = "vc-btn-menuSection";
            public readonly string MenuSectionItem = "vc-btn-menuItem";
        }
    }
}
